package org.jsola.hr.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.jsola.admin.dto.DictItemUpdateDTO;
import org.jsola.admin.entity.DictItemDO;
import org.jsola.common.PageKit;
import org.jsola.core.Page;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.IEventHandlingDAO;
import org.jsola.hr.dto.EventHandlingAddDTO;
import org.jsola.hr.dto.EventHandlingUpdateDTO;
import org.jsola.hr.entity.EventHandlingDO;
import org.jsola.hr.query.EventHandlingQuery;
import org.jsola.hr.service.ICompanyService;
import org.jsola.hr.service.IEventHandlingService;
import org.jsola.hr.service.notice.ISendNoticeService;
import org.jsola.hr.vo.EventHandlingListVO;
import org.jsola.hr.vo.EventHandlingVO;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

import static org.jsola.hr.constant.HrConstants.ALREADY_DELETE;

/**
 * 事件处理
 *
 * @author zhr
 */
@Service("hrEventHandlingServiceImpl")
@Slf4j
public class EventHandlingServiceImpl implements IEventHandlingService {

    @Autowired
    private IEventHandlingDAO eventHandlingDAO;

    @Autowired
    private ICompanyService companyService;

    @Autowired
    private ISendNoticeService sendNoticeService;

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EventHandlingVO save(EventHandlingAddDTO eventHandlingAddDTO, TokenUser tokenUser) {
        if (eventHandlingAddDTO.getCompanyId().contains(ALREADY_DELETE)) {
            throw new ParamException("选择的用工单位已被删除,请重新选择用工单位");
        }
        // 转DO
        EventHandlingDO eventHandlingDO = eventHandlingAddDTO.to(EventHandlingDO.class);
        // 保存
        eventHandlingDO = save(eventHandlingDO, tokenUser.getSiteId(), tokenUser.getUserId());
        // 发送消息通知
        try {
            sendNoticeService.sendEventHandlingNotice(eventHandlingAddDTO.getCompanyId(), eventHandlingDO, tokenUser);
        } catch (Exception e) {
            log.error("发送事件处理消息通知失败", e);
        }
        return eventHandlingDO.to(EventHandlingVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(EventHandlingUpdateDTO eventHandlingUpdateDTO, TokenUser tokenUser) {
        //转DO
        EventHandlingDO eventHandlingDO = eventHandlingUpdateDTO.to(EventHandlingDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(eventHandlingDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... eventHandlingIds) {
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) eventHandlingIds);
    }


    @Override
    public EventHandlingVO selectById(String eventHandlingId, String siteId) {
        EventHandlingDO eventHandlingDO = selectDOById(eventHandlingId, siteId);
        if (eventHandlingDO == null) {
            return null;
        }
        return eventHandlingDO.to(EventHandlingVO.class);
    }

    @Override
    public List<EventHandlingListVO> select(EventHandlingQuery eventHandlingQuery, String siteId) {
        List<EventHandlingDO> eventHandlingDOList = selectDO(eventHandlingQuery, siteId);
        if (CollectionUtils.isEmpty(eventHandlingDOList)) {
            return eventHandlingDOList == null ? null : new ArrayList<>();
        }
        return eventHandlingDOList.stream()
                .map(eventHandlingDO -> eventHandlingDO.to(EventHandlingListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(EventHandlingQuery eventHandlingQuery, String siteId) {
        Example example = buildExample(eventHandlingQuery, siteId);
        return eventHandlingDAO.selectCountByExample(example);
    }

    @Override
    public Page<EventHandlingListVO> selectPage(EventHandlingQuery eventHandlingQuery, TokenUser tokenUser) {
        List<EventHandlingListVO> eventHandlingList = eventHandlingDAO
                .selectPage(eventHandlingQuery, tokenUser.getSiteId());
        if (StringUtils.isEmpty(eventHandlingQuery.getCompanyId())) {
            List<String> companyIdList = companyService.tileCompanyIdByUser(tokenUser);
            eventHandlingList = eventHandlingList.stream()
                    .filter(event -> companyIdList.contains(event.getCompanyId()))
                    .collect(Collectors.toList());
        }
        eventHandlingList = eventHandlingList.stream()
                .sorted(Comparator.comparing(EventHandlingListVO::getMonth,Comparator.reverseOrder())
                        .thenComparing(EventHandlingListVO::getGmtCreate,Comparator.reverseOrder()))
                .collect(Collectors.toList());
        return PageKit.startPage(eventHandlingList, eventHandlingQuery.getPageNo(), eventHandlingQuery.getPageSize());
    }

    @Override
    public EventHandlingDO selectDOById(String eventHandlingId, String siteId) {
        return listById(eventHandlingId, siteId);
    }

    @Override
    public List<EventHandlingDO> selectDO(EventHandlingQuery eventHandlingQuery, String siteId) {
        Example example = buildExample(eventHandlingQuery, siteId);
        return eventHandlingDAO.selectByExample(example);
    }

    @Override
    public void updateDict(DictItemDO dictItem, DictItemUpdateDTO dictItemUpdateDTO, TokenUser tokenUser) {
        EventHandlingDO eventHandling = new EventHandlingDO();
        Example example = new Example(EventHandlingDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        if ("1225".equals(dictItem.getDictCode())) {
            example.and().andEqualTo("eventLabel", dictItem.getDictItemValue());
            eventHandling.setEventLabel(dictItemUpdateDTO.getDictItemValue());
            eventHandlingDAO.updateByExampleSelective(eventHandling, example);
        }
    }

    @Override
    public Integer selectDict(DictItemDO dictItem, TokenUser tokenUser) {
        Example example = new Example(EventHandlingDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        if ("1225".equals(dictItem.getDictCode())) {
            example.and().andEqualTo("eventLabel", dictItem.getDictItemValue());
        } else {
            return 0;
        }
        return eventHandlingDAO.selectCountByExample(example);
    }

    /**
     * 根据查询参数，构建example
     *
     * @param eventHandlingQuery 查询参数
     * @param siteId             所属站点id
     * @return example
     */
    private Example buildExample(EventHandlingQuery eventHandlingQuery, String siteId) {
        Example example = new Example(EventHandlingDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        if (!StringUtils.isEmpty(eventHandlingQuery.getCompanyId())) {
            example.and().andEqualTo("companyId", eventHandlingQuery.getCompanyId());
        }
        if (!StringUtils.isEmpty(eventHandlingQuery.getCompanyName())) {
            example.and().andEqualTo("companyName", "%" + eventHandlingQuery.getCompanyName() + "%");
        }
        if (!StringUtils.isEmpty(eventHandlingQuery.getBeginTime())) {
            example.and().andGreaterThanOrEqualTo("month", eventHandlingQuery.getBeginTime());
        }
        if (!StringUtils.isEmpty(eventHandlingQuery.getEndTime())) {
            example.and().andLessThanOrEqualTo("month", eventHandlingQuery.getEndTime());
        }
        // 排序
        ExampleKit.setExampleOrder(example, eventHandlingQuery.getOrders());
        return example;
    }
}




